package com.gitee.wsl.common.ui.ext.shape

import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Outline
import androidx.compose.ui.graphics.Path
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.LayoutDirection
import com.gitee.wsl.unit.angle.AngleUnit
import com.gitee.wsl.unit.angle.ext.plus
import kotlin.math.PI
import kotlin.math.max

class Slice2(
    private val startAngle: AngleUnit,
    private val angle: AngleUnit,
    private val innerRadius: Float = 0.5f,
    private val outerRadius: Float = 1.0f,
) : Shape{

    val degreesTo:Double  = (startAngle + angle).degrees

    val degreesFrom:Double = startAngle.degrees

    val degrees:Double = angle.degrees

    override fun createOutline(
        size: Size,
        layoutDirection: LayoutDirection,
        density: Density,
    ): Outline {
        val s = max(size.height,size.height)
        val center = s * 0.5f

        val maxBorder = 30.0 // Increases the size of the segment on each side by half of itself

        val oRadius = (s / 2) - (maxBorder / 2) // outer radius
        val iRadius = oRadius / ringRatio // inner radius

        val oc = 2.0 * PI * oRadius // outer C - circle length
        val ic = 2.0 * PI * iRadius // inner C - circle length

        val isa = (degreesTo - degreesFrom) * ic / 360.0 // inner segment arc
        val isMaxBorder = isa > maxBorder
        val border = if (isMaxBorder) maxBorder else isa
        val extraRadius = if (isMaxBorder) 0.0 else (maxBorder / 2.0) - (border / 2.0)

        val epsSafe = 0.00001 // Avoiding equal values, because the beginning may be after the end
        val oPd = ((border / 2) * 360) / oc - epsSafe // Outer padding
        val iPd = ((border / 2) * 360) / ic - epsSafe // Inner padding

        // Increasing the top arc for even indentation
        val extraOPd = separatorDegrees / 2.0 * (1.0 - (iRadius / oRadius))

        val oAStart = -90.0 + degreesFrom + oPd - extraOPd
        val oAEnd = -90.0 + degreesTo - oPd + extraOPd
        val iAStart = -90.0 + degreesFrom + iPd
        val iAEnd = -90.0 + degreesTo - iPd

        val nORadius = (oRadius + extraRadius).toFloat()
        val nIRadius = (iRadius + extraRadius).toFloat()
        val oRect = Rect(
            center - nORadius,
            center - nORadius,
            center + nORadius,
            center + nORadius,
        )
        val iRect = Rect(
            center - nIRadius,
            center - nIRadius,
            center + nIRadius,
            center + nIRadius,
        )

        val path = Path()
        path.arcTo(oRect, oAStart.toFloat(), (oAEnd - oAStart).toFloat(), false)
        path.arcTo(iRect, iAEnd.toFloat(), -(iAEnd - iAStart).toFloat(), false)
        path.close()

        return Outline.Generic(path)
    }

    companion object{
        private const val separatorDegrees = 8.0
        private const val ringRatio = 2.1
        private const val selectedOffset = 25.0
    }
}